home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- * SymbPoly.c - Generic Curve/Surface to polygon/polylines conversion routines.*
- *******************************************************************************
- * Written by Gershon Elber, July. 90. *
- ******************************************************************************/
-
- #include "symb_loc.h"
- #include "dist_pts.h"
-
- #define CURVE_PTS_DIST_RESOLUTION 10
-
- static CagdCrvStruct
- *GlblDeriv1MagSqrCrv = NULL,
- *GlblCrvtrCrv = NULL;
- static CagdRType GlblCrvtrCrvTMin, GlblCrvtrCrvTMax;
-
- static CagdPolylineStruct *SymbCrv2OptimalPolyline(CagdCrvStruct *Crv,
- int SamplesPerCurve);
- static RealType CrvCurvatureEvalFunc(RealType t);
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Routine to convert a single surface to set of triangles approximating it. M
- * FineNess is a finess control on result and the larger it is more M
- * triangles may result. M
- * A value of 10 is a good starting value. M
- * NULL is returned in case of an error, otherwise list of CagdPolygonStruct. M
- * *
- * PARAMETERS: M
- * Srf: To approximate into triangles. M
- * FineNess: Control on accuracy, the higher the finer. M
- * ComputeNormals: If TRUE, normal information is also computed. M
- * FourPerFlat: If TRUE, four triangles are created per flat surface. M
- * If FALSE, only 2 triangles are created. M
- * ComputeUV: If TRUE, UV values are stored and returned as well. M
- * *
- * RETURN VALUE: M
- * CagdPolygonStruct *: A list of polygons with optional normal and/or M
- * UV parametric information. M
- * NULL is returned in case of an error. M
- * *
- * KEYWORDS: M
- * SymbSrf2Polygons, polygonization, surface approximation M
- *****************************************************************************/
- CagdPolygonStruct *SymbSrf2Polygons(CagdSrfStruct *Srf,
- int FineNess,
- CagdBType ComputeNormals,
- CagdBType FourPerFlat,
- CagdBType ComputeUV)
- {
- /* Make sure we do not deal with constant surfaces. */
- if (Srf -> UOrder < 2 || Srf -> VOrder < 2) {
- SYMB_FATAL_ERROR(SYMB_ERR_POLY_CONST_SRF);
- return NULL;
- }
-
-
- switch (Srf -> GType) {
- case CAGD_SBEZIER_TYPE:
- return BzrSrf2Polygons(Srf, FineNess, ComputeNormals, FourPerFlat,
- ComputeUV);
- case CAGD_SBSPLINE_TYPE:
- return BspSrf2Polygons(Srf, FineNess, ComputeNormals, FourPerFlat,
- ComputeUV);
- case CAGD_SPOWER_TYPE:
- SYMB_FATAL_ERROR(SYMB_ERR_POWER_NO_SUPPORT);
- return NULL;
- default:
- SYMB_FATAL_ERROR(SYMB_ERR_UNDEF_SRF);
- return NULL;
- }
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Routine to convert a single surface to NumOfIsolines polylines in each M
- * parametric direction with SamplesPerCurve in each isoparametric curve. M
- * Polyline are always E3 of CagdPolylineStruct type. M
- * NULL is returned in case of an error, otherwise list of M
- * CagdPolylineStruct. Attempt is made to extract isolines along C1 M
- * discontinuities first. M
- * *
- * PARAMETERS: M
- * Srf: Srf to extract isoparametric curves from. M
- * NumOfIsocurves: To extarct from Srf in each (U or V) direction. M
- * SamplesPerCurve: Fineness control on piecewise linear curve M
- * approximation. M
- * Optimal: Use optimal approximation of isocurves. M
- * *
- * RETURN VALUE: M
- * CagdPolylineStruct *: List of polylines representing a piecewise linear M
- * approximation of the extracted isoparamteric M
- * curves or NULL is case of an error. M
- * *
- * KEYWORDS: M
- * SymbSrf2Polylines, polylines, isoparametric curves M
- *****************************************************************************/
- CagdPolylineStruct *SymbSrf2Polylines(CagdSrfStruct *Srf,
- int NumOfIsocurves[2],
- int SamplesPerCurve,
- int Optimal)
- {
- if (Optimal) {
- CagdCrvStruct *Crv,
- *Crvs = SymbSrf2Curves(Srf, NumOfIsocurves);
- CagdPolylineStruct *Poly,
- *Polys = NULL;
-
- for (Crv = Crvs; Crv != NULL; Crv = Crv -> Pnext) {
- Poly = SymbCrv2OptimalPolyline(Crv, SamplesPerCurve);
- Poly -> Pnext = Polys;
- Polys = Poly;
- }
-
- CagdCrvFreeList(Crvs);
- return Polys;
- }
-
-
- switch (Srf -> GType) {
- case CAGD_SBEZIER_TYPE:
- return BzrSrf2Polylines(Srf, NumOfIsocurves, SamplesPerCurve);
- case CAGD_SBSPLINE_TYPE:
- return BspSrf2Polylines(Srf, NumOfIsocurves, SamplesPerCurve);
- case CAGD_SPOWER_TYPE:
- SYMB_FATAL_ERROR(SYMB_ERR_POWER_NO_SUPPORT);
- return NULL;
- default:
- SYMB_FATAL_ERROR(SYMB_ERR_UNDEF_SRF);
- return NULL;
- }
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Routine to extract from a surface NumOfIsoline isocurve list M
- * in each param. direction. M
- * Iso parametric curves are sampled equally spaced in parametric space. M
- * NULL is returned in case of an error, otherwise list of CagdCrvStruct. M
- * *
- * PARAMETERS: M
- * Srf: To extract isoparametric curves from. M
- * NumOfIsocurves: In each (U or V) direction. M
- * *
- * RETURN VALUE: M
- * CagdCrvStruct *: List of extracted isoparametric curves. These curves M
- * inherit the order and continuity of the original Srf. M
- * NULL is returned in case of an error. M
- * *
- * KEYWORDS: M
- * SymbSrf2Curves, curves, isoparametric curves M
- *****************************************************************************/
- CagdCrvStruct *SymbSrf2Curves(CagdSrfStruct *Srf, int NumOfIsocurves[2])
- {
- switch (Srf -> GType) {
- case CAGD_SBEZIER_TYPE:
- return BzrSrf2Curves(Srf, NumOfIsocurves);
- case CAGD_SBSPLINE_TYPE:
- return BspSrf2Curves(Srf, NumOfIsocurves);
- case CAGD_SPOWER_TYPE:
- SYMB_FATAL_ERROR(SYMB_ERR_POWER_NO_SUPPORT);
- return NULL;
- default:
- SYMB_FATAL_ERROR(SYMB_ERR_UNDEF_SRF);
- return NULL;
- }
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Routine to approx. a single curve as a polyline with SamplesPerCurve M
- * samples. Polyline is always E3 CagdPolylineStruct type. M
- * NULL is returned in case of an error, otherwise CagdPolylineStruct. M
- * *
- * PARAMETERS: M
- * Crv: To approximate as a polyline. M
- * SamplesPerCurve: Number of samples to approximate with. M
- * Optimal: If TRUE, yse optimal approximation of isocurves. M
- * Otherwise, the curve is sampled using equally spaced M
- * samples in parametric space. M
- * OptiLin: If TRUE, optimize linear curves. M
- * *
- * RETURN VALUE: M
- * CagdPolylineStruct *: A polyline representing the piecewise linear M
- * approximation from, or NULL in case of an error. M
- * *
- * KEYWORDS: M
- * SymbCrv2Polyline, piecewise linear approximation, polyline M
- *****************************************************************************/
- CagdPolylineStruct *SymbCrv2Polyline(CagdCrvStruct *Crv,
- int SamplesPerCurve,
- CagdBType Optimal,
- CagdBType OptiLin)
- {
- if (Optimal)
- return SymbCrv2OptimalPolyline(Crv, SamplesPerCurve);
-
- switch (Crv -> GType) {
- case CAGD_CBEZIER_TYPE:
- return BzrCrv2Polyline(Crv, SamplesPerCurve);
- case CAGD_CBSPLINE_TYPE:
- return BspCrv2Polyline(Crv, SamplesPerCurve, NULL, OptiLin);
- case CAGD_CPOWER_TYPE:
- SYMB_FATAL_ERROR(SYMB_ERR_POWER_NO_SUPPORT);
- return NULL;
- default:
- SYMB_FATAL_ERROR(SYMB_ERR_UNDEF_CRV);
- return NULL;
- }
- }
-
- /*****************************************************************************
- * DESCRIPTION: *
- * Routine to convert a single curve to polyline with SamplesPerCurve *
- * samples. *
- * Polyline is always E3 of CagdPolylineStruct type. *
- * Curve is sampled at optimal locations as to minimize the L-infinity *
- * error between the curve and its polyline approximation. *
- * NULL is returned in case of an error, otherwise CagdPolylineStruct. *
- * *
- * PARAMETERS: *
- * Crv: To approiximate as a polyline. *
- * SamplesPerCurve: Number of samples one can take off the curve. *
- * *
- * RETURN VALUE: *
- * CagdPolylineStruct *: A polyline with SamplesPerCurve samples that *
- * approixmates Crv. *
- *****************************************************************************/
- static CagdPolylineStruct *SymbCrv2OptimalPolyline(CagdCrvStruct *Crv,
- int SamplesPerCurve)
- {
- int i;
- CagdRType *TVals;
- CagdPolylineStruct
- *P = CagdPolylineNew(SamplesPerCurve);
- CagdCrvStruct *CTmp;
- CagdPolylnStruct
- *NewPolyline = P -> Polyline;
-
- GlblCrvtrCrv = SymbCrv3DCurvatureSqr(Crv);
- CTmp = CagdCrvDerive(Crv);
- GlblDeriv1MagSqrCrv = SymbCrvDotProd(CTmp, CTmp);
- CagdCrvDomain(Crv, &GlblCrvtrCrvTMin, &GlblCrvtrCrvTMax);
-
- TVals = DistPoint1DWithEnergy(SamplesPerCurve,
- GlblCrvtrCrvTMin, GlblCrvtrCrvTMax,
- CURVE_PTS_DIST_RESOLUTION,
- CrvCurvatureEvalFunc);
-
- for (i = 0; i < SamplesPerCurve; i++) { /* Convert to E3 polyline. */
- RealType
- *R = CagdCrvEval(Crv, TVals[i]);
-
- CagdCoerceToE3(NewPolyline[i].Pt, &R, -1, Crv -> PType);
- }
-
- CagdCrvFree(GlblCrvtrCrv);
- CagdCrvFree(GlblDeriv1MagSqrCrv);
- IritFree((VoidPtr) TVals);
-
- return P;
- }
-
- /*****************************************************************************
- * DESCRIPTION: *
- * Evaluation function of curvature square. This function should return the *
- * square root of the curvature, scaled by the arclength using GlblCrvtrCrv *
- * GlblDeriv1MagSqrCrv that contain curvature square and arclength sqaure. *
- * *
- * PARAMETERS: *
- * t: Parameter at which to evalate the global curvature field. *
- * *
- * RETURN VALUE: *
- * RealType: Rstimated curvature square. *
- *****************************************************************************/
- static RealType CrvCurvatureEvalFunc(RealType t)
- {
- CagdRType CrvtrSqr, MagSqr, *R;
-
- if (t < GlblCrvtrCrvTMin)
- t = GlblCrvtrCrvTMin;
- if (t > GlblCrvtrCrvTMax)
- t = GlblCrvtrCrvTMax;
-
- R = CagdCrvEval(GlblCrvtrCrv, t);
- CrvtrSqr = fabs( R[1] / R[0] );
- R = CagdCrvEval(GlblDeriv1MagSqrCrv, t);
- MagSqr = GlblDeriv1MagSqrCrv -> PType == CAGD_PT_E1_TYPE ? R[1]
- : R[1] / R[0];
-
- return sqrt( sqrt( CrvtrSqr ) * MagSqr );
- }
-